

#include "port/GFX_ST77xx.h"

namespace GFX {

GFX_ST77xx::GFX_ST77xx(GFX_PortBase &lcd, uint32_t w, uint32_t h) : GFX_disRGB(lcd, w, h) {
    _override_datamode = 0; //  SPI MODE 0
}

GFX_ST77xx::~GFX_ST77xx() {}

void GFX_ST77xx::displayOn() { sendCommand(ST77XX_DISPON); }

void GFX_ST77xx::displayOff() { sendCommand(ST77XX_DISPOFF); }

void GFX_ST77xx::invertDisplay(bool i) { sendCommand((i) ? ST77XX_DISPON : ST77XX_DISPOFF); }

void GFX_ST77xx::writeAddrWindow(int16_t x, int16_t y, uint16_t w, uint16_t h) {
    if ((x != _currentX) || (w != _currentW)) {
        int16_t x_start = x + _xstart, x_end = x + w - 1 + _xstart;
        writeCommand(ST77XX_CASET); // Column addr set
        write32((x_start << 16) | x_end);
        _currentX = x;
        _currentW = w;
    }
    if ((y != _currentY) || (h != _currentH)) {
        int16_t y_start = y + _ystart, y_end = y + h - 1 + _ystart;
        writeCommand(ST77XX_RASET); // Row addr set
        write32((y_start << 16) | y_end);
        _currentY = y;
        _currentH = h;
    }
    writeCommand(ST77XX_RAMWR); // write to RAM
}

/**************************************************************************/
/*!
    @brief  Set origin of (0,0) and orientation of TFT display
    @param  m  The index for rotation, from 0-3 inclusive
*/
/**************************************************************************/
void GFX_ST77xx::setRotation(uint8_t m) {
    uint8_t madctl = 0;

    _rotation = m % 4; // can't be higher than 3

    switch (_rotation) {
        case 0:
            madctl  = ST77XX_MADCTL_MX | ST77XX_MADCTL_MY | ST77XX_MADCTL_RGB;
            _xstart = _colstart;
            _ystart = _rowstart;
            break;
        case 1:
            madctl  = ST77XX_MADCTL_MY | ST77XX_MADCTL_MV | ST77XX_MADCTL_RGB;
            _ystart = _colstart;
            _xstart = _rowstart;
            break;
        case 2:
            madctl  = ST77XX_MADCTL_RGB;
            _xstart = _colstart;
            _ystart = _rowstart;
            break;
        case 3:
            madctl  = ST77XX_MADCTL_MX | ST77XX_MADCTL_MV | ST77XX_MADCTL_RGB;
            _ystart = _colstart;
            _xstart = _rowstart;
            break;
    }
    sendC8D8(ST77XX_MADCTL, madctl); 
}

/**************************************************************************/
/*!
    @brief  Set origin of (0,0) of display with offsets
    @param  col  The offset from 0 for the column address
    @param  row  The offset from 0 for the row address
*/
/**************************************************************************/
void GFX_ST77xx::setColRowStart(int8_t col, int8_t row) {
    _colstart = col;
    _rowstart = row;
    switch (_rotation) {
        case 0:
            _xstart = _colstart;
            _ystart = _rowstart;
            break;
        case 1:
            _ystart = _colstart;
            _xstart = _rowstart;
            break;
        case 2:
            _xstart = _colstart;
            _ystart = _rowstart;
            break;
        case 3:
            _ystart = _colstart;
            _xstart = _rowstart;
            break;
    }
}

} // namespace GFX
